﻿using CMS.Excep;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

namespace CMS.Utils
{
    public static class MyUtils
    {
        public static string GeneratePk()
        {
            const string validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            return RandomNumberGenerator.GetString(validChars,20);
        }
        public static string FormatExceptionInfo(Exception ex)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(ex.Message);
            sb.AppendLine("StackTrace:");
            sb.AppendLine(ex.StackTrace);
            if (ex.InnerException != null)
            {
                sb.AppendLine("InnerException:");
                sb.AppendLine(FormatExceptionInfo(ex.InnerException));
            }
            return sb.ToString();
        }
        public static T JsonClone<T>(T source)
        {
            if (source == null) return default;
            var json = JsonSerializer.Serialize(source);
            return JsonSerializer.Deserialize<T>(json);
        }
        public static string Serialize<T>(T source)
        {
            var json = JsonSerializer.Serialize(source);
            return json;
        }
        public static string Md5(string str)
        {
            string pwd = "";
            MD5 md5 = MD5.Create();
            byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
            for (int i = 0; i < s.Length; i++)
            {
                pwd = pwd + s[i].ToString("X2");
            }
            return pwd.ToUpper();
        }
        public static void RestoreValues<T>(T source, T copy)
        {
            if (source == null || copy == null)
            {
                throw new MyNullException("source和copy参数不能为null");
            }

            Type type = typeof(T);
            FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            foreach (FieldInfo field in fields)
            {
                if (!field.FieldType.IsValueType && field.FieldType != typeof(string))
                {
                    throw new MyArgException($"字段 '{field.Name}' 是引用类型 ({field.FieldType.Name})，此方法仅支持值类型字段");
                }
                object value = field.GetValue(copy);
                field.SetValue(source, value);
            }
            PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            foreach (PropertyInfo property in properties)
            {
                if (!property.CanRead || !property.CanWrite)
                {
                    continue;
                }
                if (!property.PropertyType.IsValueType && property.PropertyType != typeof(string))
                {
                    throw new MyArgException($"属性 '{property.Name}' 是引用类型 ({property.PropertyType.Name})，此方法仅支持值类型属性");
                }
                object value = property.GetValue(copy);
                property.SetValue(source, value);
            }
        }

    }
}
